/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.biz.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import me.zhengjie.modules.biz.domain.*;
import me.zhengjie.modules.biz.repository.*;
import me.zhengjie.modules.biz.service.dto.CabinetDto;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.biz.service.LabService;
import me.zhengjie.modules.biz.service.dto.LabDto;
import me.zhengjie.modules.biz.service.dto.LabQueryCriteria;
import me.zhengjie.modules.biz.service.mapstruct.LabMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;

import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author Admin
* @date 2023-02-17
**/
@Service
@RequiredArgsConstructor
public class LabServiceImpl implements LabService {

    private final LabRepository labRepository;
    private final LabMapper labMapper;
    private final SensorRepository sensorRepository;
    private final SensorLogRepository sensorLogRepository;
    private final CabinetRepository cabinetRepository;
    private final UserRepository userRepository;
    @Override
    public Map<String,Object> queryAll(LabQueryCriteria criteria, Pageable pageable){
        Page<Lab> page = labRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        Page<LabDto> dto = page.map(labMapper::toDto);
        List<LabDto> resultDto = dto.getContent();
        for (LabDto labDto:resultDto) {
            if (labDto.getPid() != null) {
                if (labDto.getPid() != null) {
                    Lab lab = labRepository.findById(labDto.getPid()).orElseGet(Lab::new);
                    ValidationUtil.isNull(lab.getId(),"Lab","id",labDto.getPid());
                    labDto.setPName(lab.getName());
                }
                if (labDto.getAdministrator() != null) {
                    User user = userRepository.findById(Convert.toLong(labDto.getAdministrator())).orElseGet(User::new);
                    ValidationUtil.isNull(user.getId(),"User","id",labDto.getAdministrator());
                    labDto.setAdminName(user.getUsername());
                }
            }
        }
        return PageUtil.toPage(dto);
    }

    @Override
    public List<LabDto> queryAll(LabQueryCriteria criteria){
        List<Lab> labList = labRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder));
        List<LabDto> labDtoList = labMapper.toDto(labList);
        for (LabDto labDto : labDtoList) {
            if (labDto.getPid() != null) {
                Lab lab = labRepository.findById(labDto.getPid()).orElseGet(Lab::new);
                ValidationUtil.isNull(lab.getId(),"Lab","id",labDto.getPid());
                labDto.setPName(lab.getName());
                User user = userRepository.findById(Convert.toLong(labDto.getAdministrator())).orElseGet(User::new);
                ValidationUtil.isNull(user.getId(),"User","id",labDto.getAdministrator());
                labDto.setAdminName(user.getUsername());
            }
        }
        return labDtoList;
    }

    @Override
    @Transactional
    public LabDto findById(Integer id) {
        Lab lab = labRepository.findById(id).orElseGet(Lab::new);
        ValidationUtil.isNull(lab.getId(),"Lab","id",id);
        return labMapper.toDto(lab);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LabDto create(Lab resources) {
        resources.setAdminName(labRepository.findByadminId(resources.getAdministrator()).get("adminName"));
        return labMapper.toDto(labRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Lab resources) {
        resources.setAdminName(labRepository.findByadminId(resources.getAdministrator()).get("adminName"));
        Lab lab = labRepository.findById(resources.getId()).orElseGet(Lab::new);
        ValidationUtil.isNull( lab.getId(),"Lab","id",resources.getId());
        lab.copy(resources);
        labRepository.save(lab);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            labRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<LabDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (LabDto lab : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("实验室名称", lab.getName());
            map.put("楼层信息", lab.getFloor());
            map.put("房间号", lab.getRoomNumber());
            map.put("实验室管理员", lab.getAdminName());
            map.put("授权数量", lab.getAuthNumber());
            map.put("父实验室", lab.getPName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<Map<String, Object>> queryLabAll() {
        return labRepository.queryLabAll();
    }

    @Override
    public Map<String, Object> queryLabByRoomNumber(String roomNumber) {
//        List<ExhaustFan> exhaustFanList = exhaustFanRepository.findAll();
//        int ine = 0;
//        for (ExhaustFan exhaustFan:exhaustFanList) {
//            int[] ids =  StrUtil.splitToInt(exhaustFan.getLabName(), ",");
//            for (int ide:ids) {
//                if (ide==id){
//                    ine = exhaustFan.getId();
//                    break;
//                }
//            }if (ine!=0){
//                break;
//            }
//        }
//        ExhaustFan exhaustFan = exhaustFanRepository.findById(ine).orElseGet(ExhaustFan::new);
//
//        List<FumeHood> FumeHoodList = fumeHoodRepository.findAll();
//        int inf = 0;
//        for (FumeHood fumeHood:FumeHoodList) {
//            int[] ids =  StrUtil.splitToInt(fumeHood.getLabId(), ",");
//            for (int ide:ids) {
//                if (ide==id){
//                    inf = fumeHood.getId();
//                    break;
//                }
//            }if (inf!=0){
//                break;
//            }
//        }
//        FumeHood fumeHood = fumeHoodRepository.findById(inf).orElseGet(FumeHood::new);
//
//        List<FreshAirVentilator> freshAirVentilatorList = freshAirVentilatorRepository.findAll();
//        int infr = 0;
//        for (FreshAirVentilator freshAirVentilator:freshAirVentilatorList) {
//            int[] ids =  StrUtil.splitToInt(freshAirVentilator.getLabName(), ",");
//            for (int ide:ids) {
//                if (ide==id){
//                    ine = fumeHood.getId();
//                    break;
//                }
//            }if (ine!=0){
//                break;
//            }
//        }
//        FreshAirVentilator freshAirVentilator = freshAirVentilatorRepository.findById(ine).orElseGet(FreshAirVentilator::new);
//
//        ExhaustFan exhaustFan = exhaustFanRepository.findByLabId(id);

        return labRepository.queryLabByRoomNumber(roomNumber);
    }

    @Override
    public List<Map<String, Object>> queryLabByFloor(Integer floor) {

        return labRepository.queryLabByFloor(floor);
    }

    @Override
    public List<Map<String, Object>> queryLeftAll() {
        return labRepository.queryLeftAll();
    }

    @Override
    public List<Map<String, Object>> queryAdminAll() {
        return labRepository.findByRoleId();
    }


    public List<Map<String, Object>> queryLineInfo(Integer id, Integer startTime, Integer endTime) {
        List<Map<String, Object>> labInfo = new ArrayList<>();
        Map<String, Object> tempMap = labRepository.queryLabTemp(id);
        Map<String, Object> labTemperature = new HashMap<>(tempMap);
        Integer sensorId = null;
        ArrayList sensorLogData;
        ArrayList sensorLogTime;
        Sensor sensor = sensorRepository.findByLabIdAndType(id, 1);
        if (sensor != null) {
            sensorId = sensor.getId();
            sensorLogData = sensorLogRepository.querySensorLogData(sensorId, startTime, endTime);
            sensorLogTime = sensorLogRepository.querySensorLogTime(sensorId, startTime, endTime);
            labTemperature.put("data", sensorLogData);
            labTemperature.put("time", sensorLogTime);
            labInfo.add(labTemperature);
        }

        tempMap = labRepository.queryLabPressure(id);
        Map<String, Object> labPressure = new HashMap<>(tempMap);
        sensor = sensorRepository.findByLabIdAndType(id, 3);
        if (sensor != null) {
            sensorId = sensor.getId();
            sensorLogData = sensorLogRepository.querySensorLogData(sensorId, startTime, endTime);
            sensorLogTime = sensorLogRepository.querySensorLogTime(sensorId, startTime, endTime);
            labPressure.put("data", sensorLogData);
            labPressure.put("time", sensorLogTime);
            labInfo.add(labPressure);
        }


        tempMap = labRepository.queryLabHumidity(id);
        Map<String, Object> labHumidity = new HashMap<>(tempMap);
        sensor = sensorRepository.findByLabIdAndType(id, 2);
        if (sensor != null) {
            sensorId = sensor.getId();
            sensorLogData = sensorLogRepository.querySensorLogData(sensorId, startTime, endTime);
            sensorLogTime = sensorLogRepository.querySensorLogTime(sensorId, startTime, endTime);
            labHumidity.put("data", sensorLogData);
            labHumidity.put("time", sensorLogTime);
            labInfo.add(labHumidity);
        }


        tempMap = labRepository.queryLabVOC(id);
        Map<String, Object> labVOC = new HashMap<>(tempMap);
        sensor = sensorRepository.findByLabIdAndType(id, 5);
        if (sensor != null) {
            sensorId = sensor.getId();
            sensorLogData = sensorLogRepository.querySensorLogData(sensorId, startTime, endTime);
            sensorLogTime = sensorLogRepository.querySensorLogTime(sensorId, startTime, endTime);
            labVOC.put("data", sensorLogData);
            labVOC.put("time", sensorLogTime);
            labInfo.add(labVOC);
        }

        return labInfo;
    }

    @Override
    public List<Lab> cabinetList() {
        List<Integer> labList = cabinetRepository.cabinetList();
        ArrayList<Lab> labs = new ArrayList<>();
        for (Integer labId:labList) {
            labs.add(labRepository.findById(labId).orElseGet(Lab::new));
        }
        return labs;
    }
}
